package com.wangzhen.spring.bean.definition;

import com.wangzhen.spring.bean.factory.DefaultUserFactory;
import com.wangzhen.spring.bean.factory.UserFactory;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.wangzhen.spring.ioc.dependcy.entity.User;

import java.util.Iterator;
import java.util.ServiceLoader;

/**
 * 特殊的bean实例化演示demo
 * 1、原生ServiceLoad方式展示bean的创建
 * 2、通过spring方式替代原生ServiceLoad，创建bean
 * @author dell
 * @since 2020/10/27 8:26
 */
public class SpecialBeanInstantiationDemo {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:/META-INF/special-bean-instantiation-context.xml");
        // 3、第三种方式是通过AutowireCapableBeanFactory这种方式
        AutowireCapableBeanFactory autowireCapableBeanFactory = context.getAutowireCapableBeanFactory();
        UserFactory bean = autowireCapableBeanFactory.createBean(DefaultUserFactory.class);
        System.out.println("AutowireCapableBeanFactory#createBean的方式创建bean："+ bean);

        ServiceLoader<UserFactory> userFactoryServiceLoader = context.getBean("userFactoryServiceLoader", ServiceLoader.class);
        display(userFactoryServiceLoader);

        serviceLoaderDemo();
    }

    public static void serviceLoaderDemo() {
        // 在META-INF目录下创建一个以接口全路径为文件名 的文件 示例：com.wangzhen.spring.bean.factory.UserFactory
        // 然后在此文件中填写该接口的实现类，每个实现类一行（如果有重复的实现类，那么在下面的迭代中，会自动去重）
        // jdk 中提供的反转控制
        ServiceLoader<UserFactory> serviceLoader = ServiceLoader.load(UserFactory.class, Thread.currentThread().getContextClassLoader());
        display(serviceLoader);
    }

    private static void display(ServiceLoader<UserFactory> load) {
        Iterator<UserFactory> iterator = load.iterator();
        while (iterator.hasNext()) {
            UserFactory next = iterator.next();
            System.out.println(next);
        }
    }
}
